#ifndef _SERIAL_BUILD_
#define _SERIAL_BUILD_
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/vector.hpp>
#include "../DF_Common/basis_state.h"
#include "../DF_Common/coupling_coeff.h"
#include "../DF_Mpi_Sep/package.h"
#include "../DF_Common/com_sparse_row.h"
#include "../DF_Mpi_Sep/trans_coeff.h"
#include "../DF_Mpi_Sep/wavefun_coeff.h"
#include "../DF_Mpi_Sep/cont_term.h"
#include "../DF_Mpi_Sep/ope_term.h"
#include "../DF_Mpi_Sep/antisym_coeff.h"
#include "../DF_Mpi_Sep/tpe_term.h"

namespace boost {
  namespace serialization {
    //~~~~~~~~~~~~~~~~~~for com_sparse_row.h~~~~~~~~~~~~~~~~~~~~~~~~~//
    template<class Archive>
      void serialize(Archive &ar, SMatrix &a, const unsigned int version){
      ar & a.row_num;
      ar & a.col_num;
      ar & a.tot_num;
      ar & a.row_offsets;
      ar & a.col_indices;
      ar & a.vec_D;
      ar & a.vec_I;
      ar & a.flag_int_double;
    }
    template<class Archive>
      void serialize(Archive &ar, SMatrix_Ch &a, const unsigned int version){
      ar & a.size_ch;
      ar & a.row_num_ch;
      ar & a.col_num_ch;
      ar & a.tot_num_ch;
      ar & a.row_off_ch;
      ar & a.col_ind_ch;
      ar & a.vec_I_ch;
      ar & a.vec_D_ch;
      ar & a.flag_int_double_ch;
    }
    //~~~~~~~~~~~~~~~~~~for coupling_coefff.h~~~~~~~~~~~~~~~~~~~~~~~~~//
    template<class Archive>
      void serialize(Archive &ar, j2m2_state &a, const unsigned int version){
      ar & a.j2a;
      ar & a.m2a;
      ar & a.size;
    }
    template<class Archive>
      void serialize(Archive &ar, jajbJ_state &a, const unsigned int version){
      ar & a.j2a;
      ar & a.j2b;
      ar & a.J2;
      ar & a.index;
    }
    template<class Archive>
      void serialize(Archive &ar, TrK_state &a, const unsigned int version){
      ar & a.k1;
      ar & a.k2;
      ar & a.k3;
    }
    template<class Archive>
      void serialize(Archive &ar, J2M2 &a, const unsigned int version){
      ar & a.vec;
      ar & a.state;
    }
    template<class Archive>
      void serialize(Archive &ar, TrK_cg &a, const unsigned int version){
      ar & a.vec;
      ar & a.state;
      ar & a.exindex3;
      ar & a.inv_exindex3;
    }
    template<class Archive>
      void serialize(Archive &ar, CG_coeff &a, const unsigned int version){
      //ar & a.j2a_max;
      //ar & a.vec;
      //ar & a.J2M2_t;
      //ar & a.TrKcg_t;
      ar & a.init_info;
    }
    template<class Archive>
      void serialize(Archive &ar, JaJbJ &a, const unsigned int version){
      ar & a.vec;
      ar & a.state;
    }
    template<class Archive>
      void serialize(Archive &ar, TrK &a, const unsigned int version){
      ar & a.vec;
      ar & a.state;
      ar & a.exindex2;
      ar & a.exindex3;
    }
    template<class Archive>
      void serialize(Archive &ar, SixJ_coeff &a, const unsigned int version){
      //ar & a.j2a_max;
      ar & a.init_info;
      //ar & a.vec;
      //ar & a.JaJbJ_t;
      //ar & a.TrK_t;
    }
    template<class Archive>
      void serialize(Archive &ar, TrK_ninJ &a, const unsigned int version){
      ar & a.vec;
      ar & a.state;
      ar & a.exindex3;
    }
    template<class Archive>
      void serialize(Archive &ar, NinJ_coeff &a, const unsigned int version){
      //ar & a.j2a_max;
      ar & a.init_info;
      //ar & a.vec;
      //ar & a.JaJbJ_t;
      //ar & a.TrKninJ_t;
    }
    template<class Archive>
      void serialize(Archive &ar, Binom &a, const unsigned int version){
      ar & a.n_max;
      ar & a.init_info;
      ar & a.vec;
      ar & a.fac2vec;
    }
    //~~~~~~~~~~~~~~~~~~~~for basis_state.h~~~~~~~~~~~~~~~~~~~~~~~~~~//
    template<class Archive>
      void serialize(Archive &ar, channel_Jacobi &chan, const unsigned int version){
      ar & chan.num;
      ar & chan.J_2;
      ar & chan.T_2;
      ar & chan.E_min;
      ar & chan.E_max;
      ar & chan.indexE;
      ar & chan.indexE_beg;
    }
    template<class Archive>
      void serialize(Archive &ar, channel_TP &chan, const unsigned int version){
      ar & chan.num;
      ar & chan.J_2;
      ar & chan.T_2;
      ar & chan.T_2z;
      ar & chan.E_min;
      ar & chan.E_max;
      ar & chan.E_min_F;
      ar & chan.E_min_I;
      ar & chan.E_max_F;
      ar & chan.E_max_I;
      ar & chan.indexE;
      ar & chan.indexE_beg;
    }
    template<class Archive>
      void serialize(Archive &ar, State_SP &SP, const unsigned int version){
      ar & SP.n;
      ar & SP.l;
      ar & SP.E;
      ar & SP.j_2;
      ar & SP.tz_2;
      ar & SP.index;
    }
    template<class Archive>
      void serialize(Archive &ar, State_SPM &SP, const unsigned int version){
      ar & SP.n;
      ar & SP.l;
      ar & SP.E;
      ar & SP.j_2;
      ar & SP.m_2;
      ar & SP.tz_2;  // pn:-1: proton ; 1: neutron tz:0
      ar & SP.index;
    }
    template<class Archive>
      void serialize(Archive &ar, State_TP &TP, const unsigned int version){
      ar & TP.a;
      ar & TP.b;
      ar & TP.c;
      ar & TP.Jab_2;
      ar & TP.Tab_2;
      ar & TP.Tab_2z;  // pn
      ar & TP.J_2;
      ar & TP.T_2;
      ar & TP.T_2z;
      ar & TP.E;
      ar & TP.Par;
      ar & TP.F;  // 1: exist in final_state
      ar & TP.I;  // 1: exist in initial_state
      ar & TP.index;
    }
    template<class Archive>
      void serialize(Archive &ar, State_Conf &SC, const unsigned int version){
        ar & SC.F;
        ar & SC.I;
        ar & SC.E_ex;
      }
    template<class Archive>
      void serialize(Archive &ar, State_TPconf_E &STE, const unsigned int version){
        ar & STE.E_F;
        ar & STE.E_I;
      }
    template<class Archive>
      void serialize(Archive &ar, State_TPM &ST, const unsigned int version){
        ar & ST.a_m;
        ar & ST.b_m;
        ar & ST.c_m;
        ar & ST.Jab_2m;
        ar & ST.Tab_2z;
        ar & ST.J_2m;
        ar & ST.T_2z;
        ar & ST.E;
        ar & ST.index;
      }
    template<class Archive>
      void serialize(Archive &ar, State_Jacobi &SJ, const unsigned int version){
      ar & SJ.n12;
      ar & SJ.n3;
      ar & SJ.l12;
      ar & SJ.l3;
      ar & SJ.S12_2;
      ar & SJ.J12_2;
      ar & SJ.j3_2;
      ar & SJ.T12_2;
      ar & SJ.J_2;
      ar & SJ.T_2;
      ar & SJ.Par;
      ar & SJ.JT_channel;
      ar & SJ.E;
      ar & SJ.F;  // 1: exist in final_state
      ar & SJ.I;  // 1: exist in initial_state
      ar & SJ.index;
      ar & SJ.flag;
      ar & SJ.N_0;
      ar & SJ.L_0;
      ar & SJ.E_NL;
      ar & SJ.J2_NL;
      ar & SJ.JTNL_channel;
      ar & SJ.index_NL;
      ar & SJ.F_NL;
      ar & SJ.I_NL;
    }

    template<class Archive>
      void serialize(Archive &ar, SingleP &SP, const unsigned int version){
      ar & SP.state;
      ar & SP.state_Tz;
      ar & SP.state_TzM;
      ar & SP.index_M2J;
      ar & SP.n_max;
      ar & SP.l_max;
    }

    template<class Archive>
      void serialize(Archive &ar, TripleP &TP, const unsigned int version){
      ar & TP.state;
      ar & TP.state_Tz;
      ar & TP.state_TzM;
      ar & TP.channel;
      ar & TP.channel_Tz;
      ar & TP.JT2channel;
      ar & TP.TPconf;
      ar & TP.TPconf_Tz;
      ar & TP.TPconf_S;
      ar & TP.TPconf_Tz_S;
      ar & TP.TPconf_k;
      ar & TP.TPconf_k_Tz;
      ar & TP.TPconf_E;
      ar & TP.TPconf_E_Tz;
      ar & TP.TPconf_E_tot;
      ar & TP.E_Jac_conf;
      ar & TP.J2_max;
      ar & TP.J2_max_TP;
      ar & TP.Emax;
      ar & TP.nmax;
      ar & TP.j2max_sp;
      ar & TP.all_size_T;
      ar & TP.all_size_Tz;
      ar & TP.Emax_Final;
      ar & TP.Emax_Init;
      ar & TP.Emin_Final;
      ar & TP.Emin_Init;
      ar & TP.E_cut_conf;
    }

    template<class Archive>
      void serialize(Archive &ar, Jacobi &jaco, const unsigned int version){
      ar & jaco.state;
      ar & jaco.channel;
      ar & jaco.JT2channel;
      ar & jaco.nmax;
      ar & jaco.n12max;
      ar & jaco.n3max;
      ar & jaco.lmax;
      ar & jaco.l12max;
      ar & jaco.l3max;
      ar & jaco.J12_2max;
      ar & jaco.j3_2max;
      ar & jaco.nmin;
      ar & jaco.n12min;
      ar & jaco.n3min;
      ar & jaco.lmin;
      ar & jaco.l12min;
      ar & jaco.l3min;
      ar & jaco.J12_2min;
      ar & jaco.j3_2min;
      ar & jaco.all_size;
      ar & jaco.l12max_F;
      ar & jaco.l3max_F;
      ar & jaco.l12min_F;
      ar & jaco.l3min_F;
      ar & jaco.l12max_F;
      ar & jaco.l12max_I;
      ar & jaco.l3max_I;
      ar & jaco.l12min_I;
      ar & jaco.l3min_I;
      ar & jaco.Jaco_l123_info;
      ar & jaco.Emax_F;
      ar & jaco.Emin_F;
      ar & jaco.Emax_I;
      ar & jaco.Emin_I;
      ar & jaco.Jaco_E_info;
      ar & jaco.JT_num;
      ar & jaco.J2max;
      ar & jaco.Emax;
      ar & jaco.Jacconf;
    }

    template<class Archive>
      void serialize(Archive &ar, Jacobi_NL &jaco, const unsigned int version){
      ar & jaco.state_NL;
      ar & jaco.channel;
      ar & jaco.JT2channel;
      ar & jaco.N0_max;
      ar & jaco.L0_max;
      ar & jaco.Emax;
      ar & jaco.J2abc_max;
      ar & jaco.all_size;
      ar & jaco.channel_size_T1;

    }
    //~~~~~~~~~~~~~~~~~~~~~~~For antisymmetry~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
    template<class Archive>
      void serialize(Archive &ar, Antisym &ant, const unsigned int version){
      ar & ant.eig_val;
      ar & ant.vec_D;
      ar & ant.eig_num;
    }
    //~~~~~~~~~~~~~~~~~~~~~~~For T-coefficient~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
    template<class Archive>
      void serialize(Archive &ar, TransCoeff &T, const unsigned int version){
      ar & T.Tval_JTE;
      ar & T.Tval_vec;
      ar & T.Tval_vec_flag;
    }
    //~~~~~~~~~~~~~~~~~~~~~~~For Wave_Fun~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
    template<class Archive>
      void serialize(Archive &ar, nl_struct &a, const unsigned int version){
      ar & a.n12;
      ar & a.n3;
      ar & a.l12;
      ar & a.l3;
    }
    template<class Archive>
      void serialize(Archive &ar, kpk_struct &a, const unsigned int version){
      ar & a.n_k;
      ar & a.n_kp;
    }
    template<class Archive>
      void serialize(Archive &ar, k123_struct &a, const unsigned int version){
      ar & a.n_k12;
      ar & a.n_k3;
    }
    template<class Archive>
      void serialize(Archive &ar, lbar_struct &a, const unsigned int version){
      ar & a.lbar;
      ar & a.lbar12;
      ar & a.lbar3;
    }
    template<class Archive>
      void serialize(Archive &ar, klamb_struct &a, const unsigned int version){
      ar & a.lamb12_p;
      ar & a.lamb12;
      ar & a.lamb3_p;
      ar & a.lamb3;
    }
    template<class Archive>
      void serialize(Archive &ar, nlpnl_struct &a, const unsigned int version){
      ar & a.nl_p;
      ar & a.nl;
    }
    template<class Archive>
      void serialize(Archive &ar, Wave_Fun &w, const unsigned int version){
        //ar & w.k_mesh;
        //ar & w.p_mesh;
        //ar & w.hbar_omega;
        //ar & w.regulator_pow;
        //ar & w.Cut_Lambda;
        ar & w.lbar_max;
        ar & w.size_k123;
        ar & w.Pwave_w;
        ar & w.Pwave_x;
        ar & w.Pwave_vec;
        ar & w.Pwave_vecwx;
        ar & w.F_reg_vec;
        ar & w.nl_vec;
        ar & w.nl_state;
        ar & w.legendreP_x;
        ar & w.legendreP_w;
        ar & w.legendre_Pl;
        ar & w.legendre_PlW;
        ar & w.glbar_vec;
        ar & w.PFKglbar2_vec;
        ar & w.PFKglbar0_vec;
        ar & w.kpk_state;
        ar & w.k123_state;
        ar & w.k123_vec;
        ar & w.ksq;
        ar & w.ksq2;
        ar & w.lbar_state;
        ar & w.lbar_vec;
        ar & w.klamb_state;
        ar & w.klamb_vec;

        ar & w.lbar_state_g;
        ar & w.lbar_vec_g;
        ar & w.lbar_glbarS_max;
        ar & w.lbar_PFglbarS_max;

        ar & w.nlpnl_state;
        ar & w.nlpnl_vec;

        ar & w.Llbar_Ic_Reduced;
        ar & w.Llbar_Ic_Red_vec;

    //    ar & w.mpi_size;
    //    ar & w.mpi_layer_PFK_vec; // in PFKglbarS_save_rank
    //    ar & w.nlpnl_state;
    //    ar & w.nlpnl_vec;
        ar & w.PFKglbarS_vec;
    //    ar & w.glbarS_vec;
    //    ar & w.glbarS2_vec;
        ar & w.E_Jac_conf;
    }
    //~~~~~~~~~~~~~~~~~~~~~~~For Cont_term~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
    template<class Archive>
      void serialize(Archive &ar, Cont_term &a, const unsigned int version){
      ar & a.pf_cont;
      ar & a.vec;
      ar & a.PFK_cont_vec;
    }
    //~~~~~~~~~~~~~~~~~~~~~~~For Ope_term~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
    template<class Archive>
      void serialize(Archive &ar, Ope_term &a, const unsigned int version){
      ar & a.pf_ope;
      ar & a.vec;
    }
    //~~~~~~~~~~~~~~~~~~~~~~~For  Tpe_term~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
    template<class Archive>
    void serialize(Archive &ar, t014_struct &a, const unsigned int version){
      ar & a.t_0;
      ar & a.t_1;
      ar & a.t_4;
    }
    template<class Archive>
    void serialize(Archive &ar, l_struct &a, const unsigned int version){
      ar & a.l12p;
      ar & a.l12;
      ar & a.l3p;
      ar & a.l3;
    }
    template<class Archive>
    void serialize(Archive &ar, Hc_struct &a, const unsigned int version){
      ar & a.lbar;
      ar & a.lbar_12;
      ar & a.lbar_3;
      ar & a.i_1;
      ar & a.i_2;
      ar & a.i_3;
      ar & a.i_4;
      //ar & a.H0;
      //ar & a.H1;
      //ar & a.H2;
      //ar & a.H3;
      //ar & a.H4;
      ar & a.val;
    }
    template<class Archive>
    void serialize(Archive &ar, Ic_struct &a, const unsigned int version){
      ar & a.lamb_1;
      ar & a.lamb_2;
      ar & a.lamb_3;
      ar & a.lamb_4;
      ar & a.lamb_i;
      ar & a.lamb_j;
      ar & a.lamb_k;
      ar & a.lamb_l;
      ar & a.lamb_12;
      ar & a.lamb_3k;
      ar & a.lamb_4l;
      ar & a.q_1;
      ar & a.q_2;
      ar & a.q_3;
      ar & a.q_4;
      ar & a.val;
      ar & a.s_1;
      ar & a.s_2;
      ar & a.s_3;
      ar & a.s_4;
    }
    template<class Archive>
    void serialize(Archive &ar, Tpe_term &a, const unsigned int version){
      ar & a.lbar123_max;
      ar & a.Ic1_size;
      ar & a.Ic1_lbar_max;
      ar & a.Ic3_size;
      ar & a.Ic3_lbar_max;
      ar & a.Ic4_size;
      ar & a.Ic4_lbar_max;
      //ar & a.JaJbJ_t;
      //ar & a.cg_IntZero;
      //ar & a.cg_J2max;
      //ar & a.bino;
      //ar & a.bino_lmax;
      //ar & a.BioHat;
      //ar & a.Hat_vec;
      //ar & a.T1S_sixJ;
      //ar & a.T3S_sixJ;
      //ar & a.T1_69J;
      //ar & a.T3_69J;
      //ar & a.S12_9J;
      ar & a.l_state;
      ar & a.l_vec;
      //ar & a.t014_state;
      //ar & a.t014_vec;
      //ar & a.Ic1_index;
      //ar & a.Hc1_state;
      //ar & a.Ic3_index;
      //ar & a.Hc3_state;
      //ar & a.Ic4_index;
      //ar & a.Hc4_state;
      //ar & a.Ic3_index;
      ar & a.pf_tpe_c1;
      ar & a.pf_tpe_c3;
      ar & a.pf_tpe_c4;
      ar & a.vec;
      ar & a.vec1;
      ar & a.vec3;
      ar & a.vec4;
      ar & a.vec_flag_tot;
    }
    template<class Archive>
    void serialize(Archive &ar, Package &a, const unsigned int version){
      // ar & a.vec;
      // ar & a.vec_Tz;
      // ar & a.vec_TzM;
      // ar & a.JacA_vec;
      // ar & a.vec_anti;
      // ar & a.vec_anti_Tz;
      // ar & a.vec_flag;
      ar & a.Hbar_Omega;
      ar & a.vec_S;
      ar & a.vec_flag_S;
      ar & a.LEC_C1_P;
      ar & a.LEC_C3_P;
      ar & a.LEC_C4_P;
      ar & a.LEC_CD_P;
      ar & a.LEC_CE_P;
      ar & a.LEC_gA_P;
    }

  }
}





#endif
